package neuralmusic.brain.ga;

import java.util.concurrent.TimeUnit;

import neuralmusic.brain.InstantScheduler;
import neuralmusic.brain.gui.FireEvent;
import neuralmusic.brain.gui.FireRecord;
import neuralmusic.brain.gui.FireRecorder;
import neuralmusic.brain.module.BasicDelayed;
import neuralmusic.brain.module.Brain;
import neuralmusic.brain.module.BrainException;
import neuralmusic.brain.module.Connection;
import neuralmusic.brain.module.Excitable;
import neuralmusic.brain.module.Neuron;
import neuralmusic.brain.module.Scheduler;

public class Evaluator {
	
	double period=0.5;
		
	public FireRecorder rec=new FireRecorder();
	
	public double evaluate(final Brain brain,final Scheduler fireQueue) {

			
		
		Neuron in=(Neuron) brain.getInputs().get(0).getSink();
		Neuron out= brain.getOutputs().get(0).getSource();
		
		rec.addNeuron(in,"in");
		rec.addNeuron(out,"out");

		final Connection input = brain.getInputs().get(0);
		brain.getOutputs().get(0).setSink(Excitable.NULL);
		
		
		
		final double period=0.5;
		final double ignoreUntill=5.5*period;
		double dur=10*period;
		
		BasicDelayed myFirer = new BasicDelayed(fireQueue) {

			@Override
			public void fireImpl(Scheduler sched) {
					
				try {
					input.excite(100.0f);
				} catch (BrainException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				when = fireQueue.getCurrentTimeInSecs() + period;
				
				if (when < ignoreUntill) fireQueue.add(this);		
			}
			
		};

		BasicDelayed stopper=new BasicDelayed(fireQueue) {
			@Override
			public void fireImpl(Scheduler sched) {
				brain.stop();			
			}

//			@Override
//			public long getDelay(TimeUnit unit) {
//				return fireQueue.getDelay(unit,when);	
//			}
		};
		
		stopper.fireAt(dur);
		myFirer.fireAt(0);
		fireQueue.add(stopper);
		fireQueue.add(myFirer);
		brain.run(fireQueue);
		
		//fireQueue.getCurrentTimeInSecs();
			
		FireRecord r=rec.getEvents(out);
		
		
		double sum=0;
		
		for (FireEvent ev:r.events()){
			double t=ev.getTime();	
			if (t < ignoreUntill) continue;
			double tt=period/4.0-Math.abs(Math.IEEEremainder(t,period));
			sum+=tt;
		}
		
		return sum;
	}

}
